﻿/**
* --------------------------------------------------------------------
* jQuery-Plugin "daterangepicker.jQuery.js"
* by Scott Jehl, scott@filamentgroup.com
* reference article: http://www.filamentgroup.com/lab/update_date_range_picker_with_jquery_ui/
* demo page: http://www.filamentgroup.com/examples/daterangepicker/
* 
* Copyright (c) 2010 Filament Group, Inc
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
*
* Dependencies: jquery, jquery UI datepicker, date.js, jQuery UI CSS Framework
 
*  12.15.2010 Made some fixes to resolve breaking changes introduced by jQuery UI 1.8.7
* --------------------------------------------------------------------
*/
jQuery.fn.daterangepicker = function (settings) {
    var rangeInput = jQuery(this);

    //defaults
    var options = jQuery.extend({
        presetRanges: [
			{ text: '今天', dateStart: 'today', dateEnd: 'today' },
			{ text: '过去七天', dateStart: 'today-7days', dateEnd: 'today' },
            { text: '上月', dateStart: function () { return Date.parse('1 month ago').moveToFirstDayOfMonth(); }, dateEnd: function () { return Date.parse('1 month ago').moveToLastDayOfMonth(); } },
			{ text: '本月', dateStart: function () { return Date.parse('today').moveToFirstDayOfMonth(); }, dateEnd: 'today' },
			{ text: '本年', dateStart: function () { var x = Date.parse('today'); x.setMonth(0); x.setDate(1); return x; }, dateEnd: 'today' }
        //extras:
        //{text: 'The previous Month', dateStart: function(){ return Date.parse('1 month ago').moveToFirstDayOfMonth();  }, dateEnd: function(){ return Date.parse('1 month ago').moveToLastDayOfMonth();  } }
        //{text: 'Tomorrow', dateStart: 'Tomorrow', dateEnd: 'Tomorrow' },
        //{text: 'Ad Campaign', dateStart: '03/07/08', dateEnd: 'Today' },
        //{text: 'Last 30 Days', dateStart: 'Today-30', dateEnd: 'Today' },
        //{text: 'Next 30 Days', dateStart: 'Today', dateEnd: 'Today+30' },
        //{text: 'Our Ad Campaign', dateStart: '03/07/08', dateEnd: '07/08/08' }
		],
        //presetRanges: array of objects for each menu preset. 
        //Each obj must have text, dateStart, dateEnd. dateStart, dateEnd accept date.js string or a function which returns a date object
        presets: {
            specificDate: '指定日期',
            //allDatesBefore: 'All Dates Before', 
            //allDatesAfter: 'All Dates After', 
            dateRange: '日期区间'
        },
        rangeStartTitle: '请选择开始日期',
        rangeEndTitle: '请选择结束日期',
        nextLinkText: 'Next',
        prevLinkText: 'Prev',
        doneButtonText: '确定',
        earliestDate: Date.parse('-15years'), //earliest date allowed 
        latestDate: Date.parse('+15years'), //latest date allowed 
        constrainDates: false,
        rangeSplitter: '-', //string to use between dates in single input
        dateFormat: 'yy/mm/dd', // date formatting. Available formats: http://docs.jquery.com/UI/Datepicker/%24.datepicker.formatDate
        closeOnSelect: true, //if a complete selection is made, close the menu
        monthNames: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        arrows: false,
        appendTo: 'body',
        onClose: function () { },
        onOpen: function () { },
        onChange: function () { },
        datepickerOptions: null //object containing native UI datepicker API options
    }, settings);



    //custom datepicker options, extended by options
    var datepickerOptions = {
        onSelect: function (dateText, inst) {
            if (rp.find('.ui-daterangepicker-specificDate').is('.ui-state-active')) {
                rp.find('.range-end').datepicker('setDate', rp.find('.range-start').datepicker('getDate'));
            }

            $(this).trigger('constrainOtherPicker');

            var rangeA = fDate(rp.find('.range-start').datepicker('getDate'));
            var rangeB = fDate(rp.find('.range-end').datepicker('getDate'));

            //send back to input or inputs
            if (rangeInput.length == 2) {
                rangeInput.eq(0).val(rangeA);
                rangeInput.eq(1).val(rangeB);
            }
            else {
                rangeInput.val((rangeA != rangeB) ? rangeA + ' ' + options.rangeSplitter + ' ' + rangeB : rangeA);
            }
            //if closeOnSelect is true
            if (options.closeOnSelect) {
                if (!rp.find('li.ui-state-active').is('.ui-daterangepicker-dateRange') && !rp.is(':animated')) {
                    hideRP();
                }
            }
            options.onChange();
        },
        defaultDate: +0
    };

    //change event fires both when a calendar is updated or a change event on the input is triggered
    rangeInput.bind('change', options.onChange);

    //datepicker options from options
    options.datepickerOptions = (settings) ? jQuery.extend(datepickerOptions, settings.datepickerOptions) : datepickerOptions;

    //Capture Dates from input(s)
    var inputDateA, inputDateB = Date.parse('today');
    var inputDateAtemp, inputDateBtemp;
    if (rangeInput.size() == 2) {
        inputDateAtemp = Date.parse(rangeInput.eq(0).val());
        inputDateBtemp = Date.parse(rangeInput.eq(1).val());
        if (inputDateAtemp == null) { inputDateAtemp = inputDateBtemp; }
        if (inputDateBtemp == null) { inputDateBtemp = inputDateAtemp; }
    }
    else {
        inputDateAtemp = Date.parse(rangeInput.val().split(options.rangeSplitter)[0]);
        inputDateBtemp = Date.parse(rangeInput.val().split(options.rangeSplitter)[1]);
        if (inputDateBtemp == null) { inputDateBtemp = inputDateAtemp; } //if one date, set both
    }
    if (inputDateAtemp != null) { inputDateA = inputDateAtemp; }
    if (inputDateBtemp != null) { inputDateB = inputDateBtemp; }


    //build picker and 
    var rp = jQuery('<div class="ui-daterangepicker ui-widget ui-helper-clearfix ui-widget-content ui-corner-all"></div>');
    var rpPresets = (function () {
        var ul = jQuery('<ul class="ui-widget-content"></ul>').appendTo(rp);
        jQuery.each(options.presetRanges, function () {
            jQuery('<li class="ui-daterangepicker-' + this.text.replace(/ /g, '') + ' ui-corner-all"><a href="#">' + this.text + '</a></li>')
			.data('dateStart', this.dateStart)
			.data('dateEnd', this.dateEnd)
			.appendTo(ul);
        });
        var x = 0;
        jQuery.each(options.presets, function (key, value) {
            jQuery('<li class="ui-daterangepicker-' + key + ' preset_' + x + ' ui-helper-clearfix ui-corner-all"><span class="ui-icon ui-icon-triangle-1-e"></span><a href="#">' + value + '</a></li>')
			.appendTo(ul);
            x++;
        });

        ul.find('li').hover(
				function () {
				    jQuery(this).addClass('ui-state-hover');
				},
				function () {
				    jQuery(this).removeClass('ui-state-hover');
				})
			.click(function () {
			    rp.find('.ui-state-active').removeClass('ui-state-active');
			    jQuery(this).addClass('ui-state-active');
			    clickActions(jQuery(this), rp, rpPickers, doneBtn);
			    return false;
			});
        return ul;
    })();

    //function to format a date string        
    function fDate(date) {
        if (!date.getDate()) { return ''; }
        var day = date.getDate();
        var month = date.getMonth();
        var year = date.getFullYear();
        month++; // adjust javascript month
        var dateFormat = options.dateFormat;
        return jQuery.datepicker.formatDate(dateFormat, date);
    }


    jQuery.fn.restoreDateFromData = function () {
        if (jQuery(this).data('saveDate')) {
            jQuery(this).datepicker('setDate', jQuery(this).data('saveDate')).removeData('saveDate');
        }
        return this;
    }
    jQuery.fn.saveDateToData = function () {
        if (!jQuery(this).data('saveDate')) {
            jQuery(this).data('saveDate', jQuery(this).datepicker('getDate'));
        }
        return this;
    }

    //show, hide, or toggle rangepicker
    function showRP() {
        if (rp.data('state') == 'closed') {
            positionRP();
            rp.fadeIn(300).data('state', 'open');
            options.onOpen();
        }
    }
    function hideRP() {
        if (rp.data('state') == 'open') {
            rp.fadeOut(300).data('state', 'closed');
            options.onClose();
        }
    }
    function toggleRP() {
        if (rp.data('state') == 'open') { hideRP(); }
        else { showRP(); }
    }
    function positionRP() {
        var relEl = riContain || rangeInput; //if arrows, use parent for offsets
        var riOffset = relEl.offset(),
			side = 'left',
			val = riOffset.left,
			offRight = jQuery(window).width() - val - relEl.outerWidth();

        if (val > offRight) {
            side = 'right', val = offRight;
        }

        rp.parent().css(side, val).css('top', riOffset.top + relEl.outerHeight());
    }



    //preset menu click events	
    function clickActions(el, rp, rpPickers, doneBtn) {

        if (el.is('.ui-daterangepicker-specificDate')) {
            //Specific Date (show the "start" calendar)
            doneBtn.hide();
            rpPickers.show();
            rp.find('.title-start').text(options.presets.specificDate);
            rp.find('.range-start').restoreDateFromData().css('opacity', 1).show(400);
            rp.find('.range-end').restoreDateFromData().css('opacity', 0).hide(400);
            setTimeout(function () { doneBtn.fadeIn(); }, 400);
        }
        else if (el.is('.ui-daterangepicker-allDatesBefore')) {
            //All dates before specific date (show the "end" calendar and set the "start" calendar to the earliest date)
            doneBtn.hide();
            rpPickers.show();
            rp.find('.title-end').text(options.presets.allDatesBefore);
            rp.find('.range-start').saveDateToData().datepicker('setDate', options.earliestDate).css('opacity', 0).hide(400);
            rp.find('.range-end').restoreDateFromData().css('opacity', 1).show(400);
            setTimeout(function () { doneBtn.fadeIn(); }, 400);
        }
        else if (el.is('.ui-daterangepicker-allDatesAfter')) {
            //All dates after specific date (show the "start" calendar and set the "end" calendar to the latest date)
            doneBtn.hide();
            rpPickers.show();
            rp.find('.title-start').text(options.presets.allDatesAfter);
            rp.find('.range-start').restoreDateFromData().css('opacity', 1).show(400);
            rp.find('.range-end').saveDateToData().datepicker('setDate', options.latestDate).css('opacity', 0).hide(400);
            setTimeout(function () { doneBtn.fadeIn(); }, 400);
        }
        else if (el.is('.ui-daterangepicker-dateRange')) {
            //Specific Date range (show both calendars)
            doneBtn.hide();
            rpPickers.show();
            rp.find('.title-start').text(options.rangeStartTitle);
            rp.find('.title-end').text(options.rangeEndTitle);
            rp.find('.range-start').restoreDateFromData().css('opacity', 1).show(400);
            rp.find('.range-end').restoreDateFromData().css('opacity', 1).show(400);
            setTimeout(function () { doneBtn.fadeIn(); }, 400);
        }
        else {
            //custom date range specified in the options (no calendars shown)
            doneBtn.hide();
            rp.find('.range-start, .range-end').css('opacity', 0).hide(400, function () {
                rpPickers.hide();
            });
            var dateStart = (typeof el.data('dateStart') == 'string') ? Date.parse(el.data('dateStart')) : el.data('dateStart')();
            var dateEnd = (typeof el.data('dateEnd') == 'string') ? Date.parse(el.data('dateEnd')) : el.data('dateEnd')();
            //rp.find('.range-start').datepicker('setDate', dateStart).find('.ui-datepicker-current-day').trigger('click');
            rp.find('.range-start').datepicker('setDate', dateStart);
            rp.find('.range-end').datepicker('setDate', dateEnd).find('.ui-datepicker-current-day').trigger('click');
        }

        return false;
    }


    //picker divs
    var rpPickers = jQuery('<div class="ranges ui-widget-header ui-corner-all ui-helper-clearfix"><div class="range-start"><span class="title-start">Start Date</span></div><div class="range-end"><span class="title-end">End Date</span></div></div>').appendTo(rp);
    rpPickers.find('.range-start, .range-end')
		.datepicker(options.datepickerOptions);


    rpPickers.find('.range-start').datepicker('setDate', inputDateA);
    rpPickers.find('.range-end').datepicker('setDate', inputDateB);

    rpPickers.find('.range-start, .range-end')
		.bind('constrainOtherPicker', function () {
		    if (options.constrainDates) {
		        //constrain dates
		        if ($(this).is('.range-start')) {
		            rp.find('.range-end').datepicker("option", "minDate", $(this).datepicker('getDate'));
		        }
		        else {
		            rp.find('.range-start').datepicker("option", "maxDate", $(this).datepicker('getDate'));
		        }
		    }
		})
		.trigger('constrainOtherPicker');

    var doneBtn = jQuery('<button class="btnDone ui-state-default ui-corner-all">' + options.doneButtonText + '</button>')
	.click(function () {
	    rp.find('.ui-datepicker-current-day').trigger('click');
	    hideRP();
	})
	.hover(
			function () {
			    jQuery(this).addClass('ui-state-hover');
			},
			function () {
			    jQuery(this).removeClass('ui-state-hover');
			}
	)
	.appendTo(rpPickers);




    //inputs toggle rangepicker visibility
    jQuery(this).click(function () {
        toggleRP();
        return false;
    });
    //hide em all
    rpPickers.hide().find('.range-start, .range-end, .btnDone').hide();

    rp.data('state', 'closed');

    //Fixed for jQuery UI 1.8.7 - Calendars are hidden otherwise!
    rpPickers.find('.ui-datepicker').css("display", "block");

    //inject rp
    jQuery(options.appendTo).append(rp);

    //wrap and position
    rp.wrap('<div class="ui-daterangepickercontain"></div>');

    //add arrows (only available on one input)
    if (options.arrows && rangeInput.size() == 1) {
        var prevLink = jQuery('<a href="#" class="ui-daterangepicker-prev ui-corner-all" title="' + options.prevLinkText + '"><span class="ui-icon ui-icon-circle-triangle-w">' + options.prevLinkText + '</span></a>');
        var nextLink = jQuery('<a href="#" class="ui-daterangepicker-next ui-corner-all" title="' + options.nextLinkText + '"><span class="ui-icon ui-icon-circle-triangle-e">' + options.nextLinkText + '</span></a>');

        jQuery(this)
		.addClass('ui-rangepicker-input ui-widget-content')
		.wrap('<div class="ui-daterangepicker-arrows ui-widget ui-widget-header ui-helper-clearfix ui-corner-all"></div>')
		.before(prevLink)
		.before(nextLink)
		.parent().find('a').click(function () {
		    var dateA = rpPickers.find('.range-start').datepicker('getDate');
		    var dateB = rpPickers.find('.range-end').datepicker('getDate');
		    var diff = Math.abs(new TimeSpan(dateA - dateB).getTotalMilliseconds()) + 86400000; //difference plus one day
		    if (jQuery(this).is('.ui-daterangepicker-prev')) { diff = -diff; }

		    rpPickers.find('.range-start, .range-end ').each(function () {
		        var thisDate = jQuery(this).datepicker("getDate");
		        if (thisDate == null) { return false; }
		        jQuery(this).datepicker("setDate", thisDate.add({ milliseconds: diff })).find('.ui-datepicker-current-day').trigger('click');
		    });
		    return false;
		})
		.hover(
			function () {
			    jQuery(this).addClass('ui-state-hover');
			},
			function () {
			    jQuery(this).removeClass('ui-state-hover');
			});

        var riContain = rangeInput.parent();
    }


    jQuery(document).click(function () {
        if (rp.is(':visible')) {
            hideRP();
        }
    });

    rp.click(function () { return false; }).hide();
    return this;
}

jQuery(function ($) {
    $.datepicker.regional['zh-CN'] = {
        closeText: '关闭',
        prevText: '&#x3c;上月',
        nextText: '下月&#x3e;',
        currentText: '今天',
        monthNames: ['一月', '二月', '三月', '四月', '五月', '六月',
		'七月', '八月', '九月', '十月', '十一月', '十二月'],
        monthNamesShort: ['一', '二', '三', '四', '五', '六',
		'七', '八', '九', '十', '十一', '十二'],
        dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
        dayNamesShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
        dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'],
        weekHeader: '周',
        firstDay: 1,
        isRTL: false,
        showMonthAfterYear: true,
        yearSuffix: '年'
    };
    $.datepicker.setDefaults($.datepicker.regional['zh-CN']);
});